package com.tongji.diy.model
{
	import de.polygonal.ds.DLinkedList;
	import de.polygonal.ds.DListNode;
	
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	/**
	 * 
	 * @author xxj
	 * 
	 */

	public class RoomDataVO
	{
		public var roomIndex:uint;
		//房间顶点链表		
		public var roomPointList:DLinkedList = new DLinkedList();
		//转换矩阵
		private var _roomMatrix:Matrix = new Matrix();
		//逆转换矩阵
		private var _invertMatrix:Matrix = new Matrix();
		//包围盒，局部坐标
		private var _roomMax:Point = new Point();
		private var _roomMin:Point = new Point();
		//中心点，全局坐标
		private var _roomCenter:Point = new Point();
		//即时值
		private var _x:Number = 0;
		private var _y:Number = 0;
		private var _rotation:Number = 0;
		//保存值
		private var _registerX:Number = 0;
		private var _registerY:Number = 0;
		private var _registerRotation:Number = 0;
		
		public function RoomDataVO(roomShapePoints:Vector.<Point>, roomIndex:uint)
		{
			this.roomIndex = roomIndex
			for (var i:uint=0;i<roomShapePoints.length;i++)
			{
				var roomControlPoint:RoomControlPoint = new RoomControlPoint(roomShapePoints[i],this);
				roomPointList.append(roomControlPoint);
			}
			roomPointList.tail.next = roomPointList.head;
			roomPointList.head.prev = roomPointList.tail;
			updateBoundBox();
		}
		
		public function get registerX():Number
		{
			return _registerX;
		}
		
		public function get registerY():Number
		{
			return _registerY;
		}
		
		public function get registerRotation():Number
		{
			return -_registerRotation;
		}
		
		public function get roomMax():Point
		{
			return _roomMax;
		}
		
		public function get roomMin():Point
		{
			return _roomMin;
		}
		
		public function get roomCenter():Point
		{
			return _roomMatrix.transformPoint(_roomCenter);
		}
		
		public function get roomMatrix():Matrix
		{
			return _roomMatrix;
		}
		
		public function get x():Number
		{
			return _x;
		}
		
		public function get y():Number
		{
			return _y;
		}
		
		public function get rotation():Number
		{
			return -_rotation;
		}
		
		public function set x(x:Number):void
		{
			_x = x;
			updateMatrix();
			updateBoundBox();
		}
		
		public function set y(y:Number):void
		{
			_y = y;
			updateMatrix();
			updateBoundBox();
		}
		
		public function set rotation(rotation:Number):void
		{
			_rotation = -rotation;
			updateMatrix();
			updateBoundBox();
		}
		
		public function localToGlobal(localPoint:Point):Point
		{
			return _roomMatrix.transformPoint(localPoint);
		}
		
		public function globalToLocal(globalPoint:Point):Point
		{
			return _invertMatrix.transformPoint(globalPoint);
		}
		
		private function updateMatrix():void
		{
			_roomMatrix = new Matrix();
			_roomMatrix.rotate(_rotation*Math.PI/180);
			_roomMatrix.translate(_x,_y);
			_invertMatrix = _roomMatrix.clone();
			_invertMatrix.invert();
		}
		
		public function updateRoomCenter():void
		{
			var roomControlNode:DListNode = roomPointList.head;
			var roomMax:Point = new Point(roomControlNode.data.x,roomControlNode.data.y);
			var roomMin:Point = new Point(roomControlNode.data.x,roomControlNode.data.y);
			while(1)
			{
				roomControlNode = roomControlNode.next;
				if (roomMax.x < roomControlNode.data.x)
					roomMax.x = roomControlNode.data.x;
				if (roomMin.x > roomControlNode.data.x)
					roomMin.x = roomControlNode.data.x;
				if (roomMax.y < roomControlNode.data.y)
					roomMax.y = roomControlNode.data.y;
				if (roomMin.y > roomControlNode.data.y)
					roomMin.y = roomControlNode.data.y;
				if (roomControlNode == roomPointList.head)
					break;
			}
			_roomCenter = new Point((roomMax.x + roomMin.x)/2,(roomMax.y + roomMin.y)/2);
		}
		
		public function updateBoundBox():void
		{
			var roomControlNode:DListNode = roomPointList.head;
			_roomMax.x = roomControlNode.data.globalX;
			_roomMax.y = roomControlNode.data.globalY;
			_roomMin.x = roomControlNode.data.globalX;
			_roomMin.y = roomControlNode.data.globalY;
			while(1)
			{
				roomControlNode = roomControlNode.next;
				if (_roomMax.x < roomControlNode.data.globalX)
					_roomMax.x = roomControlNode.data.globalX;
				if (_roomMin.x > roomControlNode.data.globalX)
					_roomMin.x = roomControlNode.data.globalX;
				if (_roomMax.y < roomControlNode.data.globalY)
					_roomMax.y = roomControlNode.data.globalY;
				if (_roomMin.y > roomControlNode.data.globalY)
					_roomMin.y = roomControlNode.data.globalY;
				if (roomControlNode == roomPointList.head)
					break;
			}
		}
		
		public function register():void
		{
			_registerX = _x;
			_registerY = _y;
			_registerRotation = _rotation;
		}
	}
}